home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
592b.lha
/
TermII
/
Fran軋is
/
Exemples XCMD
/
XCMDLaser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-22
|
10KB
|
423 lines
/*
* XCMDLaser
*
* XCMD pour Term II, permettant le download de fichier PostScript
* vers une LaserWriter. On utilise les propriétes suivantes de
* la LaserWriter :
*
* - émettre un ^T entraine le retour du status de la laser
* - on doit émettre un ^D en fin de fichier
* - la laser répond par un ^D quand elle est prête à
* imprimer un nouveau fichier
* - émettre un ^C permet d'interrompre un job en cours
*
* Pour compiler avec DICE :
*
* dcc XCMDTools.o XCMDLaser.c -o XCMDLaser
*
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/asl_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>
#include <string.h>
#include <stdio.h>
#include "XCMD.h"
#include "XCMDtools.h"
/*
* DEFINE
*/
#define BUF_SIZE 80
#define BOX 50
#define TIMEOUT_LIMIT 180 /* en secondes */
/*
* VARIABLES
*/
struct MsgPort *port = NULL;
struct XCMD *XCMD = NULL;
FILE *fp = NULL;
const char PRINTER_EOF = '\x04';
const char INTERRUPT = '\x03';
const char STATUS_QUERY = '\x14';
struct FileRequester *FileRequester = NULL;
struct AslBase *AslBase = NULL;
struct Library *GadToolsBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct GadgetList *glist = NULL;
struct Window *window = NULL;
struct Screen *screen = NULL;
void *vi = NULL;
struct Gadget *GadName, *GadStop;;
struct TextAttr Topaz80 = { "topaz.font",8,0,0 };
/*
* PROTOS
*/
void End(char *);
void DownloadFile(char *);
void ExecuteXCMD(char *, void *, void *, void *);
void InitIntuition(void);
long FileSize(char *);
void HandleIntuition(void);
void UpdateBox(long,long);
void exit(int);
/*
* MAIN
*/
int main(int argc, char *argv[])
{
char buffer_name[256];
/*
* Initialisation et allocation des ressources
*/
if(!FindPort("TERM"))
End("Je n'ai pas trouvé Term II");
port = CreatePort("LASER",0);
if(!port)
End("Impossible de créer mon message port");
XCMD = CreateXCMD(port);
if(!XCMD)
End("Impossible de créer la XCMD");
AslBase = OpenLibrary(AslName,36);
if(!AslBase)
End("Pas de asl.library v36 ou plus");
struct FileRequester *FileRequester = AllocAslRequest(ASL_FileRequest,NULL);
if(!FileRequester)
End("Impossible d'allouer un file requester");
InitIntuition();
/*
* On sélectionne les fichiers et on les envoie à la laser
*/
if(AslRequestTags(FileRequester,ASL_FuncFlags,FILF_MULTISELECT|FILF_PATGAD,
ASL_Pattern,(ULONG)"#?",
ASL_Hail,(ULONG)"Multiselect",
TAG_DONE))
{
int nb_files = FileRequester->rf_NumArgs;
if(nb_files)
{
struct WBArg *wb_arg = FileRequester->rf_ArgList;
while(nb_files--)
{
NameFromLock(wb_arg->wa_Lock,buffer_name,256);
AddPart(buffer_name,wb_arg->wa_Name,256);
DownloadFile(buffer_name);
wb_arg++;
}
}
else
{
if(FileRequester->rf_File[0] != '\0')
{
strcpy(buffer_name,FileRequester->rf_Dir);
AddPart(buffer_name,FileRequester->rf_File,256);
DownloadFile(buffer_name);
}
}
}
End("Terminé sans erreurs");
}
/*
* void End(char *message)
*
* Termine le programme et libère les ressources
*/
void End(char *message)
{
puts(message);
if(XCMD) /* Soyant sûr de remettre Term II en lecture */
{
/* On n'utilise pas ExecuteXCMD car en cas
* d'erreur on reviendrait ici !
*/
XCMD->xcmd_Command = "serial_on";
if(SendXCMD(XCMD))
{
WaitPort(port);
GetMsg(port);
}
}
if(fp) fclose(fp);
if(XCMD) DeleteXCMD(XCMD);
if(port) DeletePort(port);
if(FileRequester) FreeAslRequest(FileRequester);
if(AslBase) CloseLibrary(AslBase);
if(window)
{
struct IntuiMessage *msg;
while(msg = GT_GetIMsg(window->UserPort)) GT_ReplyIMsg(msg);
CloseWindow(window);
}
if(vi) FreeVisualInfo(vi);
if(glist) FreeGadgets(glist);
if(screen) UnlockPubScreen(NULL,screen);
if(GadToolsBase) CloseLibrary(GadToolsBase);
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
exit(0);
}
/*
* void DownloadFile(char *filename)
*
* Download un fichier dont le nom est donné en paramètre
*/
void DownloadFile(char *filename)
{
unsigned char write_buffer[BUF_SIZE];
char intui_buffer[60];
long file_size = FileSize(filename);
long size = 0;
sprintf(intui_buffer,"Downloading %s (%d octets)",FilePart(filename),file_size);
GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,intui_buffer,TAG_DONE);
fp = fopen(filename,"r");
if(!fp)
End("Impossible d'ouvrir le fichier");
char c;
int i = 0;
while((c=getc(fp)) != EOF)
{
write_buffer[i] = c;
i++;
if(i == BUF_SIZE)
{
ExecuteXCMD("xcmd_swrite",write_buffer,(void *)BUF_SIZE,NULL);
size += BUF_SIZE;
HandleIntuition();
UpdateBox(size,file_size);
i = 0;
}
}
if(i>0)
ExecuteXCMD("xcmd_swrite",write_buffer,(void *)i,NULL);
/*
* On s'assure que Term II ne lira plus le serial device
* qu'à notre demande :
*/
ExecuteXCMD("serial_off",NULL,NULL,NULL);
ExecuteXCMD("xcmd_swrite",&PRINTER_EOF,(void *)1,NULL);
size+=i;
UpdateBox(size,file_size);
/*
* Attendre le ^D de l'imprimante, pendant au maximum
* 3 minutes
*/
BOOL pas_fini = TRUE;
while(pas_fini)
{
HandleIntuition();
int i;
for(i=0; i<TIMEOUT_LIMIT; i++)
{
char eof;
ExecuteXCMD("xcmd_sread",&eof,(void *)1,(void *)1000000);
if(((long)XCMD->xcmd_Args[15])>0)
{
if(eof == PRINTER_EOF)
{
pas_fini = FALSE;
break;
}
}
HandleIntuition();
}
if(pas_fini) End("L'imprimante ne répond plus");
}
ExecuteXCMD("serial_on",NULL,NULL,NULL);
fclose(fp); fp = NULL;
GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,NULL,TAG_DONE);
SetAPen(window->RPort,(UBYTE)0);
RectFill(window->RPort,BOX+4,58,BOX+4+242,70);
SetAPen(window->RPort,(UBYTE)3);
}
/*
* void ExecuteXCMD()
*
* Cette commande exécute une XCMD, et attend son retour
* ou quitte le programme en cas d'erreur
*/
void ExecuteXCMD(char *command, void *arg1, void *arg2, void *arg3)
{
if(!XCMD) End("Pas de XCMD disponible !");
XCMD->xcmd_Command = command;
XCMD->xcmd_Args[0] = arg1;
XCMD->xcmd_Args[1] = arg2;
XCMD->xcmd_Args[2] = arg3;
if(SendXCMD(XCMD))
{
WaitPort(port);
GetMsg(port);
}
else
End("SendXCMD() a échoué");
}
/*
* void InitIntuition()
*
* Initialise Intuition, la gadget toolkit, etc...
*/
void InitIntuition()
{
ExecuteXCMD("xcmd_lock_request",NULL,NULL,NULL);
screen = XCMD->xcmd_TermScreen;
UnLock(XCMD->xcmd_TermDir);
IntuitionBase = OpenLibrary("intuition.library",36);
if(!IntuitionBase)
End("Pas de intuition.library v36 ou plus");
GadToolsBase = OpenLibrary("gadtools.library",36);
if(!GadToolsBase)
End("Pas de gadtools.library v36 ou plus");
vi = GetVisualInfo(screen, TAG_DONE);
if(!vi)
End("Impossible d'obtenir les visual infos");
window = OpenWindowTags(NULL,
WA_Top, 20,
WA_Left, 15,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_PubScreen, screen,
WA_Width, 350,
WA_Height, 120,
WA_IDCMP, REFRESHWINDOW|TEXTIDCMP|BUTTONIDCMP,
WA_Title, "Downloading PostScript files (v1.0)",
WA_Activate, TRUE,
TAG_DONE);
if(!window)
End("Impossible d'ouvrir la fenêtre");
struct Gadget *gad = CreateContext(&glist);
struct NewGadget ng;
ng.ng_TextAttr = &Topaz80;
ng.ng_VisualInfo = vi;
ng.ng_LeftEdge = 10;
ng.ng_TopEdge = 30;
ng.ng_Width = 260;
ng.ng_Height = 10;
ng.ng_Flags = 0;
ng.ng_GadgetText = NULL;
gad = GadName = CreateGadget(TEXT_KIND,gad,&ng,TAG_DONE);
ng.ng_TopEdge += 60;
ng.ng_LeftEdge = 130;
ng.ng_Height = 14;
ng.ng_Width = 100;
ng.ng_GadgetText = "STOP";
gad = GadStop = CreateGadget(BUTTON_KIND,gad,&ng,TAG_DONE);
if(!gad)
End("La création des gadgets a échoué");
AddGList(window,glist,-1,-1,NULL);
RefreshGList(glist,window,NULL,-1);
GT_RefreshWindow(window,NULL);
DrawBevelBox(window->RPort,BOX,55,250,20,GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_DONE);
}
/*
* void HandleIntuition()
*
* Gère les événements transmis par Intuition
*/
void HandleIntuition()
{
struct IntuiMessage *msg;
BOOL stop = FALSE;
while(msg = GT_GetIMsg(window->UserPort))
{
ULONG class = msg->Class;
struct Gadget *gadget = msg->IAddress;
GT_ReplyIMsg(msg);
switch(class)
{
case GADGETUP :
if(gadget == GadStop)
stop = TRUE;
break;
case REFRESHWINDOW :
GT_BeginRefresh(window);
GT_EndRefresh(window,TRUE);
break;
default:
break;
}
}
if(stop)
{
ExecuteXCMD("xcmd_swrite",&INTERRUPT,(void *)1,NULL);
End("Stop by user");
}
}
/*
* long FileSize(char *)
*
* Retourne la taille en octets d'un fichier donné en paramètre
*/
long FileSize(char *filename)
{
BPTR lock = Lock(filename,ACCESS_READ);
long size = 0;
if(lock)
{
struct FileInfoBlock *fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR|MEMF_PUBLIC);
if(fib)
{
Examine(lock,fib);
size = fib->fib_Size;
FreeMem(fib,sizeof(struct FileInfoBlock));
}
UnLock(lock);
}
return(size);
}
/*
* void UpdateBox(long current, long size)
*
* Cette procédure met à jour la boite représentant l'état
* courant du téléchargement. current = nb d'octets déjà
* téléchargés, size = nb d'octets total.
*/
void UpdateBox(long current, long size)
{
long width = (242 * current) / size;
RectFill(window->RPort,BOX+4,58,BOX+width+4,70);
}